/**
 * 自己动手写操作系统
 *
 * 二级引导，负责进行硬件检测，进入保护模式，然后加载内核，并跳转至内核运行
 *
 * 作者：李述铜
 * 联系邮箱: 527676163@qq.com
 */
  	// 不必加.code32因默认就是32位
#include "os_cfg.h"

 	.text
 	.global _start

	.extern kernel_init
	.extern init_main
_start:
	mov 4(%esp),%eax
	push %eax
	call kernel_init
	jmp $KERNEL_SELECTOR_CS,$gdt_reload
gdt_reload:
	mov $KERNEL_SELECTOR_DS, %ax		// 16为数据段选择子
	mov %ax, %ds
    mov %ax, %ss
    mov %ax, %es
    mov %ax, %fs
    mov %ax, %gs
	
	// 栈设置
	mov $(stack + KERNEL_STACK_SIZE), %esp
jmp init_main

	.bss
	.comm stack, KERNEL_STACK_SIZE    // comm 声明未初始化的通用内存区域，以字节计


.macro irq_handle name num with_error_code
	.text
	.global exception_handle_\name
	.extern do_handler_\name

exception_handle_\name:
	.if \with_error_code == 0
		pushl $0
	.endif
	pushl $\num
	pusha
	push %ds
	push %es
	push %fs
	push %gs
	push %esp
	call do_handler_\name
	add $4,%esp
	pop %gs
	pop %fs
	pop %es
	pop %ds
	popa	
	add $8,%esp
	iret
.endm
.text
irq_handle default,-1,0
irq_handle divide,0,0
.text
.global simple_switch
//simple_switch(&from->stack, to->stack);
simple_switch:
	mov 8(%esp),%eax  //to->stack
	mov 4(%esp),%edx  //from->stack

	// 保存前一任务的状态
	push %ebp
	push %ebx
	push %esi
	push %edi
    mov %esp,(%edx) //将当前任务的%esp地址存储到stack中
	mov %eax,%esp //栈的地址切换
	// 加载下一任务的栈
	pop %edi
	pop %esi
	pop %ebx
	pop %ebp
  	ret




